import 'package:flutter/material.dart';

import 'my_popup_child.dart';


class MyPopupRoute extends PopupRoute{
  final MyPopupChild child;
  final Offset offsetLT, offsetRB;
  final Duration duration;
  final bool cancelable;
  final bool outsideTouchCancelable;
  final bool darkEnable;
  final List<RRect>? highlights;
  MyPopupRoute({
    required this.child,
    this.offsetLT = const Offset(0, 0),
    this.offsetRB = const Offset(0, 0),
    this.duration = const Duration(milliseconds: 300),
    this.cancelable = true,
    this.outsideTouchCancelable = true,
    this.darkEnable = true,
    this.highlights,
  });
  @override
  Color? get barrierColor => null;

  @override
  bool get barrierDismissible => true;

  @override
  String? get barrierLabel => null;

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    // TODO: implement buildPage
    return _PopRouteWidget(
      child:child,
      offsetLT: offsetLT,
      offsetRB: offsetRB,
      duration: duration,
      cancelable: cancelable,
      outsideTouchCancelable: outsideTouchCancelable,
      darkEnable: darkEnable,
      highlights: highlights,
    );
  }

  @override
  // TODO: implement transitionDuration
  Duration get transitionDuration => duration;

  static pop(BuildContext context){
    __PopRouteWidgetState.of(context)?.dismiss();
    Navigator.of(context).pop();

  }

  static setHighlights(BuildContext context, List<RRect> highlights) {
    __PopRouteWidgetState.of(context)?.highlights = highlights;
  }
}

class _PopRouteWidget extends StatefulWidget {
  final MyPopupChild child;
  final Offset offsetLT, offsetRB;
  final Duration duration;
  final bool cancelable;
  final bool outsideTouchCancelable;
  final bool darkEnable;
  final List<RRect>? highlights;

  _PopRouteWidget({
    Key? key,
    required this.child,
    this.offsetLT = const Offset(0, 0),
    this.offsetRB = const Offset(0, 0),
    this.duration = const Duration(milliseconds: 300),
    this.cancelable = true,
    this.outsideTouchCancelable = true,
    this.darkEnable = true,
    this.highlights,
  }) : super(key: key);

  @override
  State<_PopRouteWidget> createState() => __PopRouteWidgetState();
}

class __PopRouteWidgetState extends State<_PopRouteWidget> with SingleTickerProviderStateMixin{
  late Animation<double> _alphaAnim;
  late AnimationController _alphaController;
  List<RRect> _highlights = [];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    highlights = widget.highlights ?? [];
    _alphaController = AnimationController(
      vsync: this,
      duration: widget.duration,
    );
    _alphaAnim = Tween<double>(begin: 0,end: 127).animate(_alphaController);
    _alphaController.forward();
  }

  static __PopRouteWidgetState? of(BuildContext context){
    return context.findAncestorStateOfType<__PopRouteWidgetState>();
  }

  dismiss(){
    _alphaController.reverse();
    widget.child.dismiss();
  }

  set highlights(List<RRect> value){
    setState(() {
      _highlights = value;
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _alphaController.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        onWillPop: () async{
          if(widget.cancelable){
            dismiss();
            return true;
          }
          return false;
        },
        child: GestureDetector(
          onTap: (){
            if(widget.outsideTouchCancelable){
              dismiss();
              Navigator.of(context).pop();
            }
          },
          child: Stack(
            children: [
              widget.darkEnable ? AnimatedBuilder(
                  animation: _alphaController,
                  builder: (_,__){
                    return Padding(
                        padding: EdgeInsets.only(
                          left: widget.offsetLT?.dx ?? 0,
                          top: widget.offsetLT?.dy ?? 0,
                          right: widget.offsetRB?.dx ?? 0,
                          bottom: widget.offsetRB?.dy ?? 0,
                        ),
                      child: ColorFiltered(
                        colorFilter: ColorFilter.mode(
                          Colors.black.withAlpha(_alphaAnim.value.toInt()),
                          BlendMode.srcOut,
                        ),
                        child: Stack(
                          children: _buildDark(),
                        ),
                      ),
                    );
                  }) : Container(),
              widget.child,
            ],
          ),
        ),
    );
  }

  List<Widget> _buildDark(){
    List<Widget> widgets = [];
    widgets.add(
      Container(
        color: Colors.transparent,
      )
    );

    for(RRect highlight in _highlights){
      widgets.add(
        Positioned(
          left: highlight.left,
          top: highlight.top,
            child: Container(
                decoration:BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(
                    topLeft: highlight.tlRadius,
                    topRight: highlight.trRadius,
                    bottomLeft: highlight.blRadius,
                    bottomRight: highlight.brRadius,
                  ),
                ),
              width: highlight.width,
              height: highlight.height,
            ),
        )
      );
    }

    return widgets;
  }

}
